package com.ctshk.rpc.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.CharUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.goods.CommoditySeasonDTO;
import com.ctshk.rpc.goods.dto.CommodityDTO;
import com.ctshk.rpc.goods.dto.CommodityDTO2;
import com.ctshk.rpc.goods.dto.CommodityOrderDetailsDTO;
import com.ctshk.rpc.goods.dto.CommodityPageDTO;
import com.ctshk.rpc.goods.dto.htmlFive.CommodityCostAttributeDTO;
import com.ctshk.rpc.goods.dto.resp.CountVo;
import com.ctshk.rpc.goods.entity.*;
import com.ctshk.rpc.goods.mapper.*;
import com.ctshk.rpc.goods.req.CommodityAddReq;
import com.ctshk.rpc.goods.req.CommodityApprovalProcessReq;
import com.ctshk.rpc.goods.req.CommodityPageReq;
import com.ctshk.rpc.goods.req.conmodity.*;
import com.ctshk.rpc.goods.service.ICommodityService;
import com.ctshk.rpc.order.goods.dto.OrderCommodityPageListDetailDTO;
import com.ctshk.rpc.order.goods.service.IOrderService;
import com.ctshk.rpc.system.service.ISysPermissionService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-04-13
 */
@Slf4j
@DubboService
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity> implements ICommodityService {

    /**
     * 工作流服务
     */
    @DubboReference
    private ISysApprovalService sysApprovalService;

    @DubboReference
    private IOrderService orderService;

    @Autowired
    private CommodityLogMapper commodityLogMapper; // 商品操作日志mapper

    @Autowired
    private CommodityMapper commodityMapper; // 商品mapper

    @Autowired
    private CommodityKeyWordMapper keyWordMapper; // 商品關鍵字mapper

    @Autowired
    private CommodityLabelMapper labelMapper; // 商品標籤mapper

    @Autowired
    private CommodityRecommendMapper recommendMapper; // 商品推薦mapper

    @Autowired
    private CommodityFileMapper fileMapper; // 商品文件mapper

    @Autowired
    private CommodityAttributeMapper attributeMapper; // 商品属性mapper

    @Autowired
    private CommodityCostMapper costMapper; // 商品成本mapper

    @Autowired
    private CommodityCostAttributeMapper costAttributeMapper; // 商品成本属性mapper

    @Autowired
    private CommoditySalesAreaMapper salesAreaMapper; // 商品销售区域mapper

    @Autowired
    private ShoppingCommoditySpecificationsNameMapper specificationsNameMapper; // 商城商品规格名称mapper

    @Autowired
    private ShoppingCommoditySpecificationsMapper specificationsMapper; // 商城商品规格mapper

    @Autowired
    private ShoppingCommoditySpecificationsAttributeMapper specificationsAttributeMapper; // 商城商品规格屬性mapper

    @Autowired
    private CommoditySpecificationsMapper commoditySpecificationsMapper; // 商品规格属性Mapper

    @Autowired
    private CommoditySpecificationsNameMapper commoditySpecificationsNameMapper; // 商品规格Mapper

    @Autowired
    private CommoditySpecificationsAttributeMapper commoditySpecificationsAttributeMapper; // 商品规格属性值Mapper

    @Autowired
    private CommodityCostMapper commodityCostMapper;

    @Autowired
    private RegionalFreightMapper regionalFreightMapper;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @DubboReference
    private ISysPermissionService sysPermissionService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addCommodity(CommodityAddReq addReq, TokenUser currentUser) throws Exception {
        log.info("【中旅商城--新增商品--start】，入参为:{}",JSON.toJSONString(addReq));
        checkCommodity(addReq, currentUser.getId()); // 基礎數據校驗
        PublicParamSet publicParamSet = new PublicParamSet();
        setPublicParamSet(publicParamSet, currentUser.getId()); //测试时，需验证可行性
        Commodity commodity = new Commodity();
        BeanUtils.copyProperties(addReq, commodity, EntityUtil.getNullPropertyNames(addReq));
        commodity.setId(SnowflakeIdWorker.nextId());
        BeanUtils.copyProperties(publicParamSet, commodity, EntityUtil.getNullPropertyNames(publicParamSet));
        // 商品编码 PS+員工編號+月日4位+時分4位+4位隨機數字
        String commodityNumber = generateCommodityNumber(currentUser);
        commodity.setCommodityNumber(commodityNumber);
        commodityMapper.insert(commodity);
        String operationType = "save";
        setCommodityKeyWord(commodity, addReq, publicParamSet, operationType); // 設置商品關鍵字並入庫
        setCommodityLabel(commodity, addReq, publicParamSet, operationType); // 設置商品標籤並入庫
        setCommodityRecommend(commodity, addReq, publicParamSet, operationType); // 設置商品推薦並入庫
        setCommodityFile(commodity, addReq, publicParamSet, operationType); // 設置商品文件並入庫

        // 如标记"注"的功能,都在此方法下(注:商品销售区域,商品成本表,商品成本表属性,商品名规格名称/规格/规格属性)
        setCommodityAttribute(commodity, addReq, publicParamSet); // 設置商品屬性並入庫 -> 根據規格擴展：單規格，多規格
        // 商品審批流程
        updateCommodityaApprovalStatus(Integer.valueOf(addReq.getSaveType()), commodity.getId(), currentUser.getId());
        log.info("【中旅商城--新增商品--end】");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateCommodity(CommodityAddReq addReq, Long userId)
            throws Exception {
        checkCommodity(addReq, userId); // 基礎數據校驗
        PublicParamSet publicParamSet = new PublicParamSet();
        setPublicParamSet(publicParamSet, userId);

        // 更新商品主表
        Commodity commodity = commodityMapper.selectById(addReq.getId());
        BeanUtils.copyProperties(addReq, commodity, EntityUtil.getNullPropertyNames(addReq));
        commodity.setGmtModified(LocalDateTime.now());
        commodity.setModifiedId(userId);
        commodityMapper.updateById(commodity);

        publicParamSet.setCreateId(commodity.getCreateId());
        publicParamSet.setGmtCreate(commodity.getGmtCreate());

        String operationType = "update"; // 用到此参数的方法，为新增与更新的公共方法，所以这里固定为update入参
        setCommodityKeyWord(commodity, addReq, publicParamSet, operationType); // 設置商品關鍵字並入庫
        setCommodityLabel(commodity, addReq, publicParamSet, operationType); // 設置商品標籤並入庫
        setCommodityRecommend(commodity, addReq, publicParamSet, operationType); // 設置商品推薦並入庫
        setCommodityFile(commodity, addReq, publicParamSet, operationType); // 設置商品文件並入庫

        // 如标记"注"的功能,都在此方法下(注:商品销售区域,商品成本表,商品成本表属性,商品名规格名称/规格/规格属性)
        setUpCommodityAttribute(commodity, addReq, publicParamSet); // 設置商品屬性並入庫 -> 根據規格擴展：單規格，多規格
    }

    @Autowired
    private CommodityCostAttributeMapper commodityCostAttributeMapper;
    @Autowired
    private CommodityAttributeMapper commodityAttributeMapper;

    @Override
    public PageResponse<CommodityPageDTO> findCommodityPageList(CommodityPageReq pageReq, TokenUser currentUser) {

        Result<List<Long>> permissionResult = sysPermissionService.queryPermission(pageReq.getMenuId(), currentUser.getId());
        if (!permissionResult.isSuccess()) {
            SystemError result = SystemError.getDefined(permissionResult.getCode());
            throw new BusinessException(result);
        }
        //不是管理员
        if (!GlobalConstants.Role.isAdmin(currentUser.getUsername())) {
            pageReq.setIsNotAdmin(1);
            String ids = "";
            List<Long> data = permissionResult.getData();
            if(data != null && data.size() >0){
                for (Long datum : data) {
                    ids += datum + ",";
                }
            }
            if(ids.length() > 0){
                ids = ids.substring(0, ids.length() - 1);
            }
            pageReq.setUserIds(ids);
        }

        IPage<CommodityPageDTO> page = new Page<>(pageReq.getPageNo(), pageReq.getPageSize());
        // 查询商品信息
        IPage<CommodityPageDTO> commodityPageDTOIPage = commodityMapper.findCommodityPageByConditionAndApp(page, pageReq);
        List<CommodityPageDTO> records = commodityPageDTOIPage.getRecords();
        List<CommodityPageDTO> pageDTOS = EntityUtil.copyList(records, CommodityPageDTO.class);

        // 查询销量
        List<OrderCommodityPageListDetailDTO> listDetailDTOS = orderService.salesVolume();
        if (CollectionUtils.isNotEmpty(listDetailDTOS) && CollectionUtils.isNotEmpty(pageDTOS)) {
            Map<Long, OrderCommodityPageListDetailDTO> ocpldDTOMap = listDetailDTOS.stream().collect(Collectors.toMap(OrderCommodityPageListDetailDTO::getCommodityId, ocpldDTO -> ocpldDTO, (k1, k2) -> k1));
            for (CommodityPageDTO commodityPageDTO : pageDTOS) {
                // 查询商品属性
//                QueryWrapper<CommodityAttribute> commodityAttributeQueryWrapper = new QueryWrapper<>();
//                commodityAttributeQueryWrapper.eq("commodity_id", commodityPageDTO.getId());
                List<CommodityAttribute> commodityAttributes = commodityAttributeMapper.selectListByCommodityId(commodityPageDTO.getId());

                // 多规格查询商品规格
//                QueryWrapper<CommodityCostAttribute> commodityCostAttributeQueryWrapper = new QueryWrapper<>();
//                commodityCostAttributeQueryWrapper.eq("commodity_attribute_id", commodityAttributes.get(0).getId());
//                commodityCostAttributeQueryWrapper.eq("commodity_id", commodityPageDTO.getId());
                List<CommodityCostAttribute> commodityCostAttributes = commodityCostAttributeMapper.selectListByCostIdAndCommodityId(commodityAttributes.get(0).getId(),
                        commodityPageDTO.getId());
                List<CommodityCostAttributeDTO> commodityCostAttributeDTOS = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(commodityCostAttributes)) {
                    commodityCostAttributeDTOS = EntityUtil.copyList(commodityCostAttributes, CommodityCostAttributeDTO.class);
                }
                commodityPageDTO.setCommodityCostAttribute(commodityCostAttributeDTOS);
                // 设置销量
                OrderCommodityPageListDetailDTO ocpldDTO = ocpldDTOMap.get(commodityPageDTO.getId());
                if (null != ocpldDTO) {
                    commodityPageDTO.setSalesVolume(ocpldDTO.getNumber());
                }
            }
        }
        return new PageResponse<>(pageDTOS, commodityPageDTOIPage.getCurrent() == 1,
                commodityPageDTOIPage.getTotal() <= (commodityPageDTOIPage.getCurrent() * commodityPageDTOIPage.getSize()),
                commodityPageDTOIPage.getTotal(), commodityPageDTOIPage.getCurrent(), commodityPageDTOIPage.getSize());
    }

    @Override
    public Result<CommodityOrderDetailsDTO> findCommodityOrderDetailsById(Long id, Long userId) {
        if (null == id) {
            throw new BusinessException(SystemError.SYS_402);
        }
        // 获取商品信息
        CommodityDTO dbCommodityDTO = commodityMapper.findCommodityByCommodityId(id);
        CommodityOrderDetailsDTO commodityDTO = new CommodityOrderDetailsDTO();
        BeanUtils.copyProperties(dbCommodityDTO, commodityDTO);

        // 获取商品属性信息
        CommodityAttribute dbCommodityAttribute = attributeMapper.findCommodityAttributeByCommodityId(commodityDTO.getId());

        // 获取商品文件信息
        List<CommodityFile> dbCommodityFileList = fileMapper.findCommodityFileByCommodityId(commodityDTO.getId());
        List<CommodityFileReq> commodityFileReqList = new ArrayList<>();
        for (CommodityFile dbCommodityFile : dbCommodityFileList) {
            CommodityFileReq commodityFileReq = new CommodityFileReq();
            BeanUtils.copyProperties(dbCommodityFile, commodityFileReq);
            commodityFileReqList.add(commodityFileReq);
        }
        if (null != commodityFileReqList && commodityFileReqList.size() > 0) {
            commodityDTO.setCommodityFileReqList(commodityFileReqList);
        }

        // 获取商品成本信息
        CommodityCostReq commodityCostReq = costMapper.findCommodityCostReqMinPriceByCombinedIds(
                commodityDTO.getId(), dbCommodityAttribute.getId(),
                dbCommodityAttribute.getSpecificationsType());
        commodityDTO.setCommodityCostReq(commodityCostReq);
        return Result.success(commodityDTO);
    }

    @Override
    public Result<CommodityDTO> findPcCommodityById(Long id, Long userId, LocalDateTime now) {
        if (null == id) {
            throw new BusinessException(SystemError.SYS_402);
        }

        // 获取商品主表信息
        CommodityDTO commodityDTO = commodityMapper.findPcCommodityByCommodityId(id, now);

        // 获取商品关键词信息
        List<CommodityKeyWord> dbCommodityKeyWordList = keyWordMapper.findCommodityKeyWordByCommodityId(commodityDTO.getId());
        List<CommodityKeyWordReq> commodityKeyWordReqList = new ArrayList<>();
        for (CommodityKeyWord dbKeyWord : dbCommodityKeyWordList) {
            CommodityKeyWordReq keyWordReq = new CommodityKeyWordReq();
            BeanUtils.copyProperties(dbKeyWord, keyWordReq);
            commodityKeyWordReqList.add(keyWordReq);

        }
        if (null != commodityKeyWordReqList && commodityKeyWordReqList.size() > 0) {
            commodityDTO.setCommodityKeyWordReqList(commodityKeyWordReqList);
        }

        // 获取商品标签信息
        List<CommodityLabel> dbCommodityLabelList = labelMapper.findCommodityLabelByCommodityId(commodityDTO.getId());
        List<CommodityLabelReq> commodityLabelReqList = new ArrayList<>();
        for (CommodityLabel dbLabel : dbCommodityLabelList) {
            CommodityLabelReq labelReq = new CommodityLabelReq();
            BeanUtils.copyProperties(dbLabel, labelReq);
            commodityLabelReqList.add(labelReq);

        }
        if (null != commodityLabelReqList && commodityLabelReqList.size() > 0) {
            commodityDTO.setCommodityLabelReqList(commodityLabelReqList);
        }

        // 获取商品推荐信息
        List<CommodityRecommend> dbCommodityRecommendList = recommendMapper.findCommodityRecommendByCommodityId(commodityDTO.getId());
        List<CommodityRecommendReq> commodityRecommendReqList = new ArrayList<>();
        for (CommodityRecommend dbRecommend : dbCommodityRecommendList) {
            CommodityRecommendReq recommendReq = new CommodityRecommendReq();
            BeanUtils.copyProperties(dbRecommend, recommendReq);
            commodityRecommendReqList.add(recommendReq);

        }
        if (null != commodityRecommendReqList && commodityRecommendReqList.size() > 0) {
            commodityDTO.setCommodityRecommendReqList(commodityRecommendReqList);
        }

        // 获取商品文件信息
        List<CommodityFile> dbCommodityFileList = fileMapper.findCommodityFileByCommodityId(commodityDTO.getId());
        List<CommodityFileReq> commodityFileReqList = new ArrayList<>();
        for (CommodityFile dbCommodityFile : dbCommodityFileList) {
            CommodityFileReq commodityFileReq = new CommodityFileReq();
            BeanUtils.copyProperties(dbCommodityFile, commodityFileReq);
            commodityFileReqList.add(commodityFileReq);
        }
        if (null != commodityFileReqList && commodityFileReqList.size() > 0) {
            commodityDTO.setCommodityFileReqList(commodityFileReqList);
        }

        // 获取商品属性信息
        CommodityAttributeReq attributeReq = commodityDTO.getCommodityAttributeReq();
        if (attributeReq.getSpecificationsType().intValue() == 1) { // 当类型为1：即为单规格类型
            CommodityCostReq commodityCostReq = null;
            List<CommodityCost> dbCommodityCostList = costMapper.findCommodityCostByCombinedIds(commodityDTO.getId(), attributeReq.getId(), null);
            if (null != dbCommodityCostList && dbCommodityCostList.size() > 0) {
                CommodityCost dbCommodityCost = dbCommodityCostList.get(0);
                commodityCostReq = new CommodityCostReq();
                BeanUtils.copyProperties(dbCommodityCost, commodityCostReq);
            }
            if (null != commodityCostReq) {
                commodityDTO.setCommodityCostReq(commodityCostReq);
            }
        } else { // 当类型为2：即为多规格类型
            setMultiSpecificationRelatedParamInfo(commodityDTO, attributeReq);
        }
        return Result.success(commodityDTO);
    }

    @Override
    public Result<CommodityDTO> findCommodityById(Long id) {
        log.info("【中旅商城--获取商品信息--start】，入参为：{}",id);
        if (null == id) {
            throw new BusinessException(SystemError.SYS_402);
        }

        CommodityDTO commodityDTO = new CommodityDTO();
        Commodity commodity = commodityMapper.selectById(id);
        log.info("【中旅商城--获取商品信息DTO】，返参为：{}", JSON.toJSONString(commodityDTO));
        if(commodity != null){
            BeanUtils.copyProperties(commodity, commodityDTO);
            // 获取商品成本表列表
            List<CommodityCost> commodityCostList = commodityCostMapper.findCommodityCostListByCommodityId(commodityDTO.getId());
            if(commodityCostList != null && commodityCostList.size() > 0){
                List<CommodityCostSingleReq> commodityCostSingleReqList = new ArrayList<>();
                for (CommodityCost commodityCost : commodityCostList) {
                    CommodityCostSingleReq commodityCostSingleReq = new CommodityCostSingleReq();
                    BeanUtils.copyProperties(commodityCost, commodityCostSingleReq);
                    commodityCostSingleReqList.add(commodityCostSingleReq);
                }
                commodityDTO.setCommodityCostReqList(commodityCostSingleReqList);
            }
        }

        // 获取商品规格信息
        CommodityAttribute attributeByCommodityId = commodityAttributeMapper.findCommodityAttributeByCommodityId(commodity.getId());
        if (null != attributeByCommodityId){
            CommodityAttributeReq commodityAttributeReq = EntityUtil.copy(attributeByCommodityId,CommodityAttributeReq.class);
            commodityDTO.setCommodityAttributeReq(commodityAttributeReq);
        }

        // 获取商品关键词信息
        List<CommodityKeyWord> dbCommodityKeyWordList = keyWordMapper.findCommodityKeyWordByCommodityId(commodityDTO.getId());
        log.info("【中旅商城--获取商品关键字】，返参为：{}", JSON.toJSONString(dbCommodityKeyWordList));

        List<CommodityKeyWordReq> commodityKeyWordReqList = new ArrayList<>();
        for (CommodityKeyWord dbKeyWord : dbCommodityKeyWordList) {
            CommodityKeyWordReq keyWordReq = new CommodityKeyWordReq();
            BeanUtils.copyProperties(dbKeyWord, keyWordReq);
            commodityKeyWordReqList.add(keyWordReq);
        }

        if (null != commodityKeyWordReqList && commodityKeyWordReqList.size() > 0) {
            commodityDTO.setCommodityKeyWordReqList(commodityKeyWordReqList);
        }

        // 获取商品标签信息
        List<CommodityLabel> dbCommodityLabelList = labelMapper.findCommodityLabelByCommodityId(commodityDTO.getId());
        log.info("【中旅商城--获取商品标签信息】，返参为：{}", JSON.toJSONString(dbCommodityLabelList));

        List<CommodityLabelReq> commodityLabelReqList = new ArrayList<>();
        for (CommodityLabel dbLabel : dbCommodityLabelList) {
            CommodityLabelReq labelReq = new CommodityLabelReq();
            BeanUtils.copyProperties(dbLabel, labelReq);
            commodityLabelReqList.add(labelReq);

        }
        if (null != commodityLabelReqList && commodityLabelReqList.size() > 0) {
            commodityDTO.setCommodityLabelReqList(commodityLabelReqList);
        }

        // 获取商品运费模板信息
        if(commodityDTO.getCommoditySpecificationsNameId() != null){
            CommoditySpecificationsName commoditySpecificationsName = commoditySpecificationsNameMapper.selectById(commodityDTO.getCommoditySpecificationsNameId());
            if(commoditySpecificationsName != null){
                commodityDTO.setCommoditySpecificationsNameId(commoditySpecificationsName.getId());
                commodityDTO.setCommoditySpecificationsName(commoditySpecificationsName.getSpecificationsName());
            }
        }

        // 获取商品推荐信息
        List<CommodityRecommend> dbCommodityRecommendList = recommendMapper.findCommodityRecommendByCommodityId(commodityDTO.getId());
        log.info("【中旅商城--获取商品推荐信息】，返参为：{}", JSON.toJSONString(dbCommodityRecommendList));

        List<CommodityRecommendReq> commodityRecommendReqList = new ArrayList<>();
        for (CommodityRecommend dbRecommend : dbCommodityRecommendList) {
            CommodityRecommendReq recommendReq = new CommodityRecommendReq();
            BeanUtils.copyProperties(dbRecommend, recommendReq);
            commodityRecommendReqList.add(recommendReq);

        }
        if (null != commodityRecommendReqList && commodityRecommendReqList.size() > 0) {
            commodityDTO.setCommodityRecommendReqList(commodityRecommendReqList);
        }

        // 获取商品文件信息
        List<CommodityFile> dbCommodityFileList = fileMapper.findCommodityFileByCommodityId(commodityDTO.getId());
        log.info("【中旅商城--获取商品文件信息】，返参为：{}", JSON.toJSONString(dbCommodityFileList));

        List<CommodityFileReq> commodityFileReqList = new ArrayList<>();
        for (CommodityFile dbCommodityFile : dbCommodityFileList) {
            CommodityFileReq commodityFileReq = new CommodityFileReq();
            BeanUtils.copyProperties(dbCommodityFile, commodityFileReq);
            commodityFileReqList.add(commodityFileReq);
        }
        if (null != commodityFileReqList && commodityFileReqList.size() > 0) {
            commodityDTO.setCommodityFileReqList(commodityFileReqList);
        }

        // 获取商品属性信息
        CommodityAttributeReq attributeReq = commodityDTO.getCommodityAttributeReq();
        log.info("【中旅商城--获取商品属性信息】，返参为：{}", JSON.toJSONString(attributeReq));
        if(attributeReq != null){
            if (attributeReq.getSpecificationsType().intValue() == 1) { // 当类型为1：即为单规格类型
                CommodityCostReq commodityCostReq = null;
                List<CommodityCost> dbCommodityCostList = costMapper.findCommodityCostByCombinedIds(commodityDTO.getId(), attributeReq.getId(), null);
                log.info("【中旅商城--获取商品成本信息】，返参为：{}", JSON.toJSONString(dbCommodityCostList));
                if (null != dbCommodityCostList && dbCommodityCostList.size() > 0) {
                    CommodityCost dbCommodityCost = dbCommodityCostList.get(0);
                    commodityCostReq = EntityUtil.copy(dbCommodityCost,CommodityCostReq.class);
//                BeanUtils.copyProperties(dbCommodityCost, commodityCostReq);
//                .copyProperties(commodityCostReq ,dbCommodityCost);
                }
                if (null != commodityCostReq) {
                    commodityDTO.setCommodityCostReq(commodityCostReq);
                }
            } else { // 当类型为2：即为多规格类型
                setMultiSpecificationRelatedParamInfo(commodityDTO, attributeReq);
            }
        }
        log.info("【中旅商城--获取商品信息--end】");
        return Result.success(commodityDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateCommodityStatusById(Long id, Integer saleStatus, TokenUser tokenUser) {
        // 根据ID获取当前更新的商品
        Commodity dbCommodity = commodityMapper.selectById(id);
        if (null == dbCommodity) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23012);
        }
        Long userId = tokenUser.getId();
        PublicParamSet publicParamSet = new PublicParamSet();
        setPublicParamSet(publicParamSet, userId); // 对象公共属性设置

        // 更新商品状态
        dbCommodity.setSaleStatus(saleStatus);

        if(saleStatus.equals(2)){
            // 下架时移除ES缓存的对应商品信息
//            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest();
//            restHighLevelClient.indices().delete();
        }

        dbCommodity.setModifiedId(userId);
        dbCommodity.setGmtModified(publicParamSet.getGmtModified());
        commodityMapper.updateById(dbCommodity);

        // 更新商品状态，记录到操作日志
        CommodityLog commodityLog = new CommodityLog();
        commodityLog.setOriginalStatus(dbCommodity.getSaleStatus());
        commodityLog.setCommodityId(dbCommodity.getId());
        commodityLog.setCommodityName(dbCommodity.getCommodityName());
        commodityLog.setOriginalApprovalStatus(dbCommodity.getApprovalStatus());
        commodityLog.setApprovalStatus(dbCommodity.getApprovalStatus());
        commodityLog.setStatus(dbCommodity.getSaleStatus());
        commodityLog.setModifiedName(tokenUser.getUsername());
        BeanUtils.copyProperties(publicParamSet, commodityLog, EntityUtil.getNullPropertyNames(publicParamSet));
        commodityLogMapper.insert(commodityLog);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void commodityApprovalProcess(CommodityApprovalProcessReq approvalProcessReq, TokenUser tokenUser) throws Exception {
        // userId = 1344284712813568L;//目前固定用户和类型测试
        Long userId = tokenUser.getId();
        LocalDateTime now = LocalDateTime.now();
        CommodityLog commodityLog = new CommodityLog();
        commodityLog.setCommodityId(approvalProcessReq.getCommodityId());
        commodityLog.setCommodityName(approvalProcessReq.getCommodityName());
        commodityLog.setOriginalApprovalStatus(approvalProcessReq.getCurrentApprovalStatus());
        commodityLog.setOriginalStatus(approvalProcessReq.getSaleStatus());
        commodityLog.setStatus(approvalProcessReq.getSaleStatus());
        commodityLog.setCreateId(userId);
        commodityLog.setGmtCreate(now);
        commodityLog.setModifiedId(userId);
        commodityLog.setGmtModified(now);
        commodityLog.setModifiedName(tokenUser.getUsername());
        commodityLog.setIsDeleted(IsDeletedCode.NO.getCode());
        if (2 == approvalProcessReq.getToApprovalStatus()) { // 2：审批中流程
            updateCommodityaApprovalStatus(approvalProcessReq.getToApprovalStatus(),
                    approvalProcessReq.getCommodityId(), userId);
            commodityLog.setApprovalStatus(approvalProcessReq.getToApprovalStatus());
            commodityLogMapper.insert(commodityLog);
        } else if (Arrays.asList("3", "4").contains(approvalProcessReq.getToApprovalStatus().toString())) {  // 3：审批通过；4：审批未通过
            Commodity commodity = commodityMapper.selectById(approvalProcessReq.getCommodityId());
            // 调用审批服务
            Result<ApprovalCheckDTO> result = sysApprovalService.check(commodity.getApprovalId(), userId, approvalProcessReq.getToApprovalStatus(), approvalProcessReq.getComments());
            if (!result.isSuccess()) {
                SystemError error = SystemError.getDefined(result.getCode());
                throw new BusinessException(error);
            }

            if (result.getData().getIsFinish()) { // 审批结果
                commodity.setApprovalStatus(approvalProcessReq.getToApprovalStatus());
                baseMapper.updateById(commodity);
                commodityLog.setApprovalStatus(approvalProcessReq.getToApprovalStatus());
                commodityLogMapper.insert(commodityLog);
            }
        }
    }

    private void setMultiSpecificationRelatedParamInfo(CommodityDTO commodityDTO, CommodityAttributeReq attributeReq) {
        // 商品成本查询
        List<CommodityCostSingleReq> dbCommodityCostSingleList = costMapper.findCommodityCostAndAttributeByCombinedIds(commodityDTO.getId(), attributeReq.getId());
        if (dbCommodityCostSingleList != null) {
            commodityDTO.setCommodityCostReqList(dbCommodityCostSingleList);
            List<Long> specificationsAttributeId = new ArrayList<>();
            for (CommodityCostSingleReq costSingleReq : dbCommodityCostSingleList) {
                CommodityCostAttributeReq costAttributeReq = costSingleReq.getCommodityCostAttributeReq();
                if (null != costAttributeReq) {
                    if (!specificationsAttributeId.contains(costAttributeReq.getSpecificationsAttributeOneId())) {
                        specificationsAttributeId.add(costAttributeReq.getSpecificationsAttributeOneId());
                    }
                    if (!specificationsAttributeId.contains(costAttributeReq.getSpecificationsAttributeTwoId())) {
                        specificationsAttributeId.add(costAttributeReq.getSpecificationsAttributeTwoId());
                    }
                }
            }
            // 商品规格查询属性
            List<ShoppingCommoditySpecificationsAttribute> specificationsAttributeList = specificationsAttributeMapper.selectBatchByIds(specificationsAttributeId);

            Long specificationsNameId = null;
            List<Long> specificationsId = new ArrayList<>();
            if (null != specificationsAttributeList && specificationsAttributeList.size() > 0) {
                specificationsNameId = specificationsAttributeList.get(0).getSpecificationsNameId();
                for (ShoppingCommoditySpecificationsAttribute specificationsAttribute : specificationsAttributeList) {
                    if (!specificationsId.contains(specificationsAttribute.getSpecificationsId())) {
                        specificationsId.add(specificationsAttribute.getSpecificationsId());
                    }
                }

                // =========== 多规格类型中，用到了商品规格模板参数，所以这里需要取规格模板数据去做一个比对操作 Start===========
                ShoppingCommoditySpecificationsName specificationsName = specificationsNameMapper.selectInfoById(specificationsNameId);
                ShoppingCommoditySpecificationsNameReq specificationsNameReq = new ShoppingCommoditySpecificationsNameReq();
                BeanUtils.copyProperties(specificationsName, specificationsNameReq);

                List<ShoppingCommoditySpecifications> dbShoppingCommoditySpecificationsList = specificationsMapper.findSpecificationsByNameId(specificationsNameId);
                List<ShoppingCommoditySpecificationsReq> specificationsReqs = new ArrayList<>();

                // 通过指定的规格名称下的规格二级菜单，去比对本次操作的具体属性
                for (ShoppingCommoditySpecifications dbSpecifications : dbShoppingCommoditySpecificationsList) {
                    ShoppingCommoditySpecificationsReq specificationsReq = new ShoppingCommoditySpecificationsReq();
                    BeanUtils.copyProperties(dbSpecifications, specificationsReq);
                    List<ShoppingCommoditySpecificationsAttributeReq> specificationsAttributeReqs = new ArrayList<>();
                    for (ShoppingCommoditySpecificationsAttribute specificationsAttribute : specificationsAttributeList) {
                        if (specificationsNameId.longValue() == specificationsAttribute.getSpecificationsNameId().longValue()
                                && (specificationsReq.getId().longValue() == specificationsAttribute.getSpecificationsId().longValue())) {
                            ShoppingCommoditySpecificationsAttributeReq specificationsAttributeReq = new ShoppingCommoditySpecificationsAttributeReq();
                            BeanUtils.copyProperties(specificationsAttribute, specificationsAttributeReq);
                            specificationsAttributeReqs.add(specificationsAttributeReq);
                        }
                    }
                    specificationsReq.setShoppingCommoditySpecificationsAttributeReqList(specificationsAttributeReqs);
                    specificationsReqs.add(specificationsReq);
                }
                specificationsNameReq.setShoppingCommoditySpecificationsReqList(specificationsReqs);
                // =========== 多规格类型中，用到了商品规格模板参数，所以这里需要取规格模板数据去做一个比对操作 End===========

                commodityDTO.setShoppingCommoditySpecificationsNameReq(specificationsNameReq);
            }
        }
    }

//	public PageResponse<CommodityPageDTO> findCommodityPageList(CommodityPageReq pageReq, TokenUser currentUser) {
//		IPage<CommodityPageDTO> page = new Page<CommodityPageDTO>(pageReq.getPageNo(),pageReq.getPageSize());
//		IPage<CommodityPageDTO> iPage = commodityMapper.findCommodityPageByCondition(page, pageReq);
//		List<CommodityPageDTO> recordsList = iPage.getRecords();
//		List<CommodityPageDTO> pageDTOList = EntityUtil.copyList(recordsList, CommodityPageDTO.class);
//
//		// 查询销量
//		List<OrderCommodityPageListDetailDTO> ocpldDTOs = orderService.salesVolume();
//		if (CollectionUtils.isNotEmpty(ocpldDTOs) && CollectionUtils.isNotEmpty(pageDTOList)) {
//			Map<Long, OrderCommodityPageListDetailDTO> ocpldDTOMap = ocpldDTOs.stream().collect(Collectors.toMap(OrderCommodityPageListDetailDTO::getCommodityId, ocpldDTO -> ocpldDTO,(k1, k2)->k1));
//			for (CommodityPageDTO commodityPageDTO : pageDTOList) {
//				OrderCommodityPageListDetailDTO ocpldDTO = ocpldDTOMap.get(commodityPageDTO.getId());
//				if (null != ocpldDTO) {
//					commodityPageDTO.setSalesVolume(ocpldDTO.getNumber());
//				}
//			}
//		}
//		return new PageResponse<>(pageDTOList, iPage.getCurrent() == 1,
//				iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()),
//				iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
//	}

    /**
     * 常用的对象公共属性参数设置
     *
     * @param publicParamSet 常用属性参数对象
     * @param userId         用户ID
     */
    private void setPublicParamSet(PublicParamSet publicParamSet, Long userId) {
        LocalDateTime now = LocalDateTime.now();
        publicParamSet.setCreateId(userId);
        publicParamSet.setGmtCreate(now);
        publicParamSet.setModifiedId(userId);
        publicParamSet.setGmtModified(now);
        publicParamSet.setIsDeleted(IsDeletedCode.NO.getCode());
    }

    /**
     * 商品審批流程
     *
     * @param operationType 固定2為-提交審批
     * @param commodityId   商品主鍵ID
     * @param userId        用戶id
     * @throws Exception 異常
     */
    private void updateCommodityaApprovalStatus(Integer operationType, Long commodityId, Long userId) throws Exception {
        if (2 == operationType.intValue()) {
            Commodity commodity = commodityMapper.selectById(commodityId);
            // todo 创建一个审批流程
            // userId = 1344284712813568L;//目前固定用户和类型测试
            long approvalTypeId = SysApprovalType.ADD_COMMODITY.getCode();
            try {
                Result<ApprovalStartDTO> result = sysApprovalService.start(SystemBusinessType.COMMODITY.getCode(), approvalTypeId, commodity.getId(), userId, null, null);
                if (result.isSuccess()) {
                    commodity.setApprovalId(result.getData().getApprovalId());
                    commodity.setApprovalStatus(GoodsApprovalStatusConstants.UNDER_APPROVAL.getCode()); // 审批状态：1：待提交；2：审批中；3：s审批通过；4：审批未通过
                    commodityMapper.updateById(commodity);
                } else {
                    throw new BusinessException(SystemError.MALL_MERCHANDISE_23013);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23014);
            }
        }
    }

    private void setCommodityAttribute(Commodity commodity, CommodityAddReq addReq, PublicParamSet publicParamSet) {
        CommodityAttributeReq commodityAttributeReq = addReq.getCommodityAttributeReq(); // 商品属性参数对象
        if (null == commodityAttributeReq.getSpecificationsType() || commodityAttributeReq.getSpecificationsType() == 0
                || commodityAttributeReq.getSpecificationsType() > 2) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23015);
        }
        CommodityAttribute commodityAttribute = new CommodityAttribute();
        BeanUtils.copyProperties(commodityAttributeReq, commodityAttribute, EntityUtil.getNullPropertyNames(commodityAttributeReq));
        BeanUtils.copyProperties(publicParamSet, commodityAttribute, EntityUtil.getNullPropertyNames(publicParamSet));
        commodityAttribute.setCommodityId(commodity.getId());
        attributeMapper.insert(commodityAttribute);

        setCommoditySalesArea(commodity, commodityAttribute, addReq, publicParamSet);  // 設置商品销售区域並入庫

        if (commodityAttributeReq.getSpecificationsType() == 1) { // 1-單規格
            setCommodityCost(commodity, commodityAttribute, addReq, publicParamSet); // 设置单规格-商品成本並入庫
        } else { // 2-多規格
            setCommodityCostAndAttribute(commodity, commodityAttribute, addReq, publicParamSet);// 设置多规格-商品成本並入庫
        }
    }

    private void setCommoditySalesArea(Commodity commodity, CommodityAttribute commodityAttribute, CommodityAddReq addReq,
                                       PublicParamSet publicParamSet) {
        CommoditySalesAreaReq commoditySalesAreaReq = addReq.getCommoditySalesAreaReq();
        List<Integer> areaTypeList = commoditySalesAreaReq.getAreaTypeList();
        if (CollectionUtils.isEmpty(areaTypeList) || !Arrays.asList(1, 2, 3).containsAll(areaTypeList)) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23016);
        }

        for (Integer areaType : areaTypeList) {
            CommoditySalesArea commoditySalesArea = new CommoditySalesArea();
            BeanUtils.copyProperties(commoditySalesAreaReq, commoditySalesArea, EntityUtil.getNullPropertyNames(commoditySalesAreaReq));
            BeanUtils.copyProperties(publicParamSet, commoditySalesArea, EntityUtil.getNullPropertyNames(publicParamSet));
            commoditySalesArea.setAreaType(areaType);
            commoditySalesArea.setCommodityId(commodity.getId());
            commoditySalesArea.setCommodityAttributeId(commodityAttribute.getId());
            salesAreaMapper.insert(commoditySalesArea);
        }
    }

    private void setCommodityCostAndAttribute(Commodity commodity, CommodityAttribute commodityAttribute,
                                              CommodityAddReq addReq, PublicParamSet publicParamSet) {
        // 商品规格-树级三层结构
        Map<Long, String> attributeOldNewId = new HashMap<Long, String>(); // key：oldId，value:newId,名称
        setShoppingCommoditySpecificationsAttribute(commodity, addReq, attributeOldNewId, publicParamSet, "save"); // 设置商城商品规格属性并入库

        // 商品成本
        List<CommodityCostReq> commodityCostReqList = addReq.getCommodityCostReqList();
        if (null != commodityCostReqList && commodityCostReqList.size() > 0) {
            List<CommodityCost> commodityCostList = new ArrayList<CommodityCost>();
            List<CommodityCostAttribute> commodityCostAttributeList = new ArrayList<CommodityCostAttribute>();

            for (CommodityCostReq commodityCostReq : commodityCostReqList) {
                CommodityCost commodityCost = new CommodityCost();
                CommodityCostAttribute commodityCostAttribute = new CommodityCostAttribute();

                // --------------- 设置 商品成本属性 start ---------------
                Long commodityCostAttributeId = IdWorker.getId();
                commodityCostAttribute.setId(commodityCostAttributeId);
//                if (attributeOldNewId.containsKey(commodityCostReq.getSpecificationsAttributeOneId())) {
//                    String[] attributeIdAndName = attributeOldNewId.get(commodityCostReq.getSpecificationsAttributeOneId()).split(",");
//                    commodityCostAttribute.setSpecificationsAttributeOneId(Long.valueOf(attributeIdAndName[0]));
//                    commodityCostAttribute.setSpecificationsAttributeOneName(attributeIdAndName[1]);
//                }
//                if (attributeOldNewId.containsKey(commodityCostReq.getSpecificationsAttributeTwoId())) {
//                    String[] attributeIdAndName = attributeOldNewId.get(commodityCostReq.getSpecificationsAttributeTwoId()).split(",");
//                    commodityCostAttribute.setSpecificationsAttributeTwoId(Long.valueOf(attributeIdAndName[0]));
//                    commodityCostAttribute.setSpecificationsAttributeTwoName(attributeIdAndName[1]);
//                }
                commodityCostAttribute.setSpecificationsAttributeOneId(commodityCostReq.getSpecificationsAttributeOneId());
                commodityCostAttribute.setSpecificationsAttributeTwoId(commodityCostReq.getSpecificationsAttributeTwoId());
                commodityCostAttribute.setSpecificationsAttributeOneName(commodityCostReq.getSpecificationsAttributeOneName());
                commodityCostAttribute.setSpecificationsAttributeTwoName(commodityCostReq.getSpecificationsAttributeTwoName());
                commodityCostAttribute.setCommodityAttributeId(commodityAttribute.getId());
                commodityCostAttribute.setCommodityId(commodity.getId());
                BeanUtils.copyProperties(publicParamSet, commodityCostAttribute, EntityUtil.getNullPropertyNames(publicParamSet));
                commodityCostAttributeList.add(commodityCostAttribute);
                // --------------- 设置 商品成本属性 end  ---------------

                // =============== 设置 商品成本 start ===============
                BeanUtils.copyProperties(commodityCostReq, commodityCost, EntityUtil.getNullPropertyNames(commodityCostReq));
                BeanUtils.copyProperties(publicParamSet, commodityCost, EntityUtil.getNullPropertyNames(publicParamSet));
                commodityCost.setCommodityAttributeId(commodityAttribute.getId());
                commodityCost.setCommodityId(commodity.getId());
                commodityCost.setCostAttributeId(commodityCostAttributeId); // 商品成本属性ID
                commodityCostList.add(commodityCost);
                // =============== 设置 商品成本 end ===============
            }
            costAttributeMapper.insertBatchSomeColumn(commodityCostAttributeList);
            costMapper.insertBatchSomeColumn(commodityCostList);
        }
    }

    private void setShoppingCommoditySpecificationsAttribute(Commodity commodity, CommodityAddReq addReq, Map<Long, String> attributeOldNewId
            , PublicParamSet publicParamSet, String operationType) {
        // 获取规格一级数据
        ShoppingCommoditySpecificationsNameReq specificationsNameReq = addReq.getShoppingCommoditySpecificationsNameReq();
        if (null == specificationsNameReq) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23017);
        }
        if ("update".equals(operationType)) { // 更新时，每次重新新增，删除旧数据，主键ID不变。(主要为了不用去数据库重新做比对逻辑)
            Long specificationsNameId = specificationsNameReq.getId();
            specificationsNameMapper.deleteById(specificationsNameReq.getId());
            List<ShoppingCommoditySpecifications> dbSpecificationsList = specificationsMapper.findSpecificationsByNameId(specificationsNameId);
            List<Long> specificationsIds = dbSpecificationsList.stream().map(p -> p.getId()).collect(Collectors.toList());
            if(specificationsIds != null && specificationsIds.size() > 0){
                specificationsMapper.deleteBatchIds(specificationsIds);
            }
            if(specificationsNameId != null && specificationsIds != null){
                List<ShoppingCommoditySpecificationsAttribute> dbSpecificationsAttributeList = specificationsAttributeMapper.findSpecificationsAttributeByNameId(specificationsNameId, specificationsIds);
                List<Long> specificationsAttributeIds = dbSpecificationsAttributeList.stream().map(p -> p.getId()).collect(Collectors.toList());
                if(specificationsAttributeIds != null){
                    specificationsAttributeMapper.deleteBatchIds(specificationsAttributeIds);
                }
            }
        }
        ShoppingCommoditySpecificationsName specificationsName = new ShoppingCommoditySpecificationsName();
        BeanUtils.copyProperties(specificationsNameReq, specificationsName, EntityUtil.getNullPropertyNames(specificationsNameReq));
        BeanUtils.copyProperties(publicParamSet, specificationsName, EntityUtil.getNullPropertyNames(publicParamSet));
        specificationsNameMapper.insert(specificationsName);

        // 获取规格二级数据
        List<ShoppingCommoditySpecificationsReq> specificationsReqList = specificationsNameReq.getShoppingCommoditySpecificationsReqList();
        specificationsReqList = specificationsReqList!=null?specificationsReqList:new ArrayList<>();
        for (int i = 0; i < specificationsReqList.size(); i++) {
            ShoppingCommoditySpecificationsReq specificationsReq = specificationsReqList.get(i);
            ShoppingCommoditySpecifications specifications = new ShoppingCommoditySpecifications();
            BeanUtils.copyProperties(specificationsReq, specifications, EntityUtil.getNullPropertyNames(specificationsReq));
            BeanUtils.copyProperties(publicParamSet, specifications, EntityUtil.getNullPropertyNames(publicParamSet));
            specifications.setSpecificationsNameId(specificationsName.getId());
            specificationsMapper.insert(specifications);
            // 获取规格三级数据
            List<ShoppingCommoditySpecificationsAttributeReq> ficationsAttributeReqList = specificationsReq.getShoppingCommoditySpecificationsAttributeReqList();
            if (null != ficationsAttributeReqList) {
                List<ShoppingCommoditySpecificationsAttribute> specificationsAttributeList = new ArrayList<ShoppingCommoditySpecificationsAttribute>();
                for (ShoppingCommoditySpecificationsAttributeReq specificationsAttributeReq : ficationsAttributeReqList) {
                    ShoppingCommoditySpecificationsAttribute specificationsAttribute = new ShoppingCommoditySpecificationsAttribute();
                    BeanUtils.copyProperties(specificationsAttributeReq, specificationsAttribute, EntityUtil.getNullPropertyNames(specificationsAttributeReq));
                    Long newId = IdWorker.getId();
                    specificationsAttribute.setId(newId);
                    specificationsAttribute.setSpecificationsNameId(specificationsName.getId());
                    specificationsAttribute.setSpecificationsId(specifications.getId());
                    BeanUtils.copyProperties(publicParamSet, specificationsAttribute, EntityUtil.getNullPropertyNames(publicParamSet));
                    // 将规格数据存到MAP，外围数据需要用到
                    attributeOldNewId.put(specificationsAttributeReq.getOldId(), newId + "," + specificationsAttribute.getAttributeName());
                    specificationsAttributeList.add(specificationsAttribute);
                }
                specificationsAttributeMapper.insertBatchSomeColumn(specificationsAttributeList);
            }
        }
    }

    /**
     * 设置商品成本
     *
     * @param commodity          商品对象
     * @param commodityAttribute 商品属性对象
     * @param addReq             入参
     * @param publicParamSet     通用属性赋值对象
     */
    private void setCommodityCost(Commodity commodity, CommodityAttribute commodityAttribute,
                                  CommodityAddReq addReq, PublicParamSet publicParamSet) {
        List<CommodityCostReq> commodityCostReqList = addReq.getCommodityCostReqList();
        if (null != commodityCostReqList && commodityCostReqList.size() > 0) {
            CommodityCostReq commodityCostReq = commodityCostReqList.get(0); // i注意：单规格，只有一条数据
            CommodityCost commodityCost = new CommodityCost();
            BeanUtils.copyProperties(commodityCostReq, commodityCost, EntityUtil.getNullPropertyNames(commodityCostReq));
            BeanUtils.copyProperties(publicParamSet, commodityCost, EntityUtil.getNullPropertyNames(publicParamSet));
            commodityCost.setCommodityAttributeId(commodityAttribute.getId());
            commodityCost.setCommodityId(commodity.getId());
            costMapper.insert(commodityCost);
        }
    }

    /**
     * 新增商品--设置商品文件--入库
     * @param commodity
     * @param addReq
     * @param publicParamSet
     * @param operationType
     */
    private void setCommodityFile(Commodity commodity, CommodityAddReq addReq, PublicParamSet publicParamSet, String operationType) {
        List<CommodityFileReq> commodityFileReqList = addReq.getCommodityFileReqList();
        log.info("【中旅商城--设置商品文件--入库】，返参为：{}",JSON.toJSONString(commodityFileReqList));
        Integer pictureCount = 0;
        if (null == commodityFileReqList || commodityFileReqList.size() == 0) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23018);
        }
        if ("update".equals(operationType)) {
            List<CommodityFile> dbCommodityFileList = fileMapper.findCommodityFileByCommodityId(commodity.getId());
            log.info("【中旅商城--设置商品文件--查询商品文件对象】，返参为:{}",JSON.toJSONString(dbCommodityFileList));
            List<Long> commodityFileIds = dbCommodityFileList.stream().map(p -> p.getId()).collect(Collectors.toList());
            fileMapper.deleteBatchIds(commodityFileIds);
        }
        List<CommodityFile> CommodityFileList = new ArrayList<CommodityFile>();
        for (CommodityFileReq commodityFileReq : commodityFileReqList) {
            CommodityFile commodityFile = new CommodityFile();
            if (commodityFileReq.getFileType() == 2) {
                pictureCount++;
            }
            BeanUtils.copyProperties(commodityFileReq, commodityFile, EntityUtil.getNullPropertyNames(commodityFileReq));
            BeanUtils.copyProperties(publicParamSet, commodityFile, EntityUtil.getNullPropertyNames(publicParamSet));
            commodityFile.setCommodityId(commodity.getId());
            CommodityFileList.add(commodityFile);
        }

        // 联调阶段暂不加校验
//		if (pictureCount == 0 || pictureCount > 5) {
//			throw new BusinessException(SystemError.MALL_MERCHANDISE_23018);
//		}
        fileMapper.insertBatchSomeColumn(CommodityFileList);
    }

    /**
     * 新增商品--设置商品推荐--入库
     * @param commodity
     * @param addReq
     * @param publicParamSet
     * @param operationType
     */
    private void setCommodityRecommend(Commodity commodity, CommodityAddReq addReq, PublicParamSet publicParamSet, String operationType) {
        // String commodityRecommendStr = addReq.getCommodityRecommendStr();
        List<String> commodityRecommendListParam = addReq.getCommodityRecommendList();
        log.info("【中旅商城--设置商品推荐--查询商品推荐列表】，入参为：{}",JSON.toJSONString(commodityRecommendListParam));
        if (CollectionUtils.isEmpty(commodityRecommendListParam)) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23019);
        } else {
            if ("update".equals(operationType)) {
                List<CommodityRecommend> dbCommodityRecommendList = recommendMapper.findCommodityRecommendByCommodityId(commodity.getId());
                List<Long> commodityRecommendIds = dbCommodityRecommendList.stream().map(p -> p.getId()).collect(Collectors.toList());
                recommendMapper.deleteBatchIds(commodityRecommendIds);
            }
            List<CommodityRecommend> commodityRecommendList = new ArrayList<CommodityRecommend>();
            // String [] recommends = commodityRecommendStr.split(",");
            for (String recommend : commodityRecommendListParam) {
                CommodityRecommend commodityRecommend = new CommodityRecommend();
                BeanUtils.copyProperties(publicParamSet, commodityRecommend, EntityUtil.getNullPropertyNames(publicParamSet));
                commodityRecommend.setCommodityId(commodity.getId());
                commodityRecommend.setRecommendType(Integer.valueOf(recommend));
                commodityRecommendList.add(commodityRecommend);
            }
            recommendMapper.insertBatchSomeColumn(commodityRecommendList);
        }
    }

    private void setCommodityLabel(Commodity commodity, CommodityAddReq addReq, PublicParamSet publicParamSet, String operationType) {
        // String commodityLabelStr = addReq.getCommodityLabelStr();
        List<String> commodityLabelListParam = addReq.getCommodityLabelList();
        if ("update".equals(operationType)) {
            List<CommodityLabel> dbCommodityLabelList = labelMapper.findCommodityLabelByCommodityId(commodity.getId());
            List<Long> commodityLabelIds = dbCommodityLabelList.stream().map(p -> p.getId()).collect(Collectors.toList());
            labelMapper.deleteBatchIds(commodityLabelIds);
        }
        List<CommodityLabel> commodityLabelList = new ArrayList<CommodityLabel>();
        // String [] lables = commodityLabelStr.split(",");
        for (String lable : commodityLabelListParam) {
            CommodityLabel commodityLabel = new CommodityLabel();
            BeanUtils.copyProperties(publicParamSet, commodityLabel, EntityUtil.getNullPropertyNames(publicParamSet));
            commodityLabel.setCommodityId(commodity.getId());
            commodityLabel.setLabelType(Integer.valueOf(lable));
            commodityLabelList.add(commodityLabel);
        }
        if(commodityLabelList.size() > 0){
            labelMapper.insertBatchSomeColumn(commodityLabelList);
        }
    }

    private void setCommodityKeyWord(Commodity commodity, CommodityAddReq addReq, PublicParamSet publicParamSet, String operationType) throws Exception {
        String commodityKeyWordStr = addReq.getCommodityKeyWordStr();
        if (StringUtils.isBlank(commodityKeyWordStr)) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23021);
        } else {
            if ("update".equals(operationType)) {
                List<CommodityKeyWord> dbCommodityKeyWordList = keyWordMapper.findCommodityKeyWordByCommodityId(commodity.getId());
                List<Long> commodityKeyWordIds = dbCommodityKeyWordList.stream().map(p -> p.getId()).collect(Collectors.toList());
                keyWordMapper.deleteBatchIds(commodityKeyWordIds);
            }
            List<CommodityKeyWord> commodityKeyWordList = new ArrayList<CommodityKeyWord>();
            String[] keyWords = commodityKeyWordStr.split(",");
            for (String keyWord : keyWords) {
                CommodityKeyWord keyWordReq = new CommodityKeyWord();
                BeanUtils.copyProperties(publicParamSet, keyWordReq, EntityUtil.getNullPropertyNames(publicParamSet));
                keyWordReq.setCommodityId(commodity.getId());
                keyWordReq.setType(1); // 關鍵詞-固定為1
                keyWordReq.setWords(keyWord);
                commodityKeyWordList.add(keyWordReq);
            }
            keyWordMapper.insertBatchSomeColumn(commodityKeyWordList);
        }
    }

    private void checkCommodity(CommodityAddReq addReq, Long userId) {
        if (null == addReq) {
            throw new BusinessException(SystemError.SYS_402);
        }
        if (null == addReq.getCommodityClassificationName() || addReq.getCommodityClassificationName().length() > 80) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23022);
        }
        if (null == addReq.getCommodityIntroduce() || addReq.getCommodityIntroduce().length() > 300) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23023);
        }
        if (null == addReq.getChargePersonId() || null == addReq.getChargePersonName()) { // 前端沒傳默認為登入用戶
            addReq.setChargePersonId(userId);
            addReq.setChargePersonName(null);
        }
        if (null == addReq.getSaveType()) {
            throw new BusinessException(SystemError.SYS_402);
        } else {
            if ("1".equals(addReq.getSaveType())) {
                addReq.setApprovalStatus(GoodsApprovalStatusConstants.TO_BE_SUBMITTED.getCode());
            }
            addReq.setSaleStatus(2); // 新增數據，默認都為下架
        }
    }


    private void setUpCommodityAttribute(Commodity commodity, CommodityAddReq addReq, PublicParamSet publicParamSet) {
        CommodityAttributeReq commodityAttributeReq = addReq.getCommodityAttributeReq();
        if (null == commodityAttributeReq.getSpecificationsType() || commodityAttributeReq.getSpecificationsType() == 0
                || commodityAttributeReq.getSpecificationsType() > 2) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23024);
        }
        CommodityAttribute dbCommodityAttribute = attributeMapper.selectById(commodityAttributeReq.getId());
        BeanUtils.copyProperties(commodityAttributeReq, dbCommodityAttribute, EntityUtil.getNullPropertyNames(commodityAttributeReq));
        BeanUtils.copyProperties(publicParamSet, dbCommodityAttribute, EntityUtil.getNullPropertyNames(publicParamSet));
        dbCommodityAttribute.setCommodityId(commodity.getId());
        attributeMapper.updateById(dbCommodityAttribute);

        setUpCommoditySalesArea(commodity, dbCommodityAttribute, addReq, publicParamSet);  // 設置商品销售区域並入庫

        if (commodityAttributeReq.getSpecificationsType() == 1) { // 1-單規格，多規格
            setUpCommodityCost(commodity, dbCommodityAttribute, addReq, publicParamSet); // 设置单规格-商品成本並入庫
        } else { // 2-多規格
            setUpCommodityCostAndAttribute(commodity, dbCommodityAttribute, addReq, publicParamSet);// 设置多规格-商品成本並入庫
        }
    }

    private void setUpCommodityCostAndAttribute(Commodity commodity, CommodityAttribute commodityAttribute,
                                                CommodityAddReq addReq, PublicParamSet publicParamSet) {
        // 商品规格-树级三层结构
        Map<Long, String> attributeOldNewId = new HashMap<Long, String>();
        setShoppingCommoditySpecificationsAttribute(commodity, addReq, attributeOldNewId, publicParamSet, "update"); // 设置商城商品规格属性并入库

        // 商品成本
        List<CommodityCostReq> commodityCostReqList = addReq.getCommodityCostReqList();
        if (null != commodityCostReqList && commodityCostReqList.size() > 0) {
            List<CommodityCost> commodityCostList = new ArrayList<CommodityCost>();
            List<CommodityCostAttribute> commodityCostAttributeList = new ArrayList<CommodityCostAttribute>();
            List<Long> commodityCostAttributeIds = new ArrayList<Long>();
            if (null != commodity.getId() && null != commodityAttribute.getId()) {
                List<CommodityCostAttribute> dbCommodityCostAttribute = costAttributeMapper.findCostAttributeByCommodityIdAndAttributeId(commodity.getId(), commodityAttribute.getId());
                commodityCostAttributeIds = dbCommodityCostAttribute.stream().map(p -> p.getId()).collect(Collectors.toList());
                costAttributeMapper.deleteBatchIds(commodityCostAttributeIds);
            }

            if (null != commodity.getId() && null != commodityAttribute.getId() && (null != commodityCostAttributeIds && commodityCostAttributeIds.size() > 0)) {
                List<CommodityCost> dbCommodityCostList = costMapper.findCommodityCostByCombinedIds(commodity.getId(), commodityAttribute.getId(), commodityCostAttributeIds);
                List<Long> commodityCostListIds = dbCommodityCostList.stream().map(p -> p.getId()).collect(Collectors.toList());
                costMapper.deleteBatchIds(commodityCostListIds);
            }
            for (CommodityCostReq commodityCostReq : commodityCostReqList) {
                CommodityCost commodityCost = new CommodityCost();
                CommodityCostAttribute commodityCostAttribute = new CommodityCostAttribute();

                // --------------- 设置 商品成本属性 start ---------------
                Long commodityCostAttributeId = IdWorker.getId();
                commodityCostAttribute.setId(commodityCostAttributeId);
                commodityCostAttribute.setSpecificationsAttributeOneId(commodityCostReq.getSpecificationsAttributeOneId());
                commodityCostAttribute.setSpecificationsAttributeOneName(commodityCostReq.getSpecificationsAttributeOneName());
                commodityCostAttribute.setSpecificationsAttributeTwoId(commodityCostReq.getSpecificationsAttributeTwoId());
                commodityCostAttribute.setSpecificationsAttributeTwoName(commodityCostReq.getSpecificationsAttributeTwoName());
                if (attributeOldNewId.containsKey(commodityCostReq.getSpecificationsAttributeOneId())) {
                    String[] attributeIdAndName = attributeOldNewId.get(commodityCostReq.getSpecificationsAttributeOneId()).split(",");
                    commodityCostAttribute.setSpecificationsAttributeOneId(Long.valueOf(attributeIdAndName[0]));
                    commodityCostAttribute.setSpecificationsAttributeOneName(attributeIdAndName[1]);
                }
                if (attributeOldNewId.containsKey(commodityCostReq.getSpecificationsAttributeTwoId())) {
                    String[] attributeIdAndName = attributeOldNewId.get(commodityCostReq.getSpecificationsAttributeTwoId()).split(",");
                    commodityCostAttribute.setSpecificationsAttributeTwoId(Long.valueOf(attributeIdAndName[0]));
                    commodityCostAttribute.setSpecificationsAttributeTwoName(attributeIdAndName[1]);
                }
                commodityCostAttribute.setCommodityAttributeId(commodityAttribute.getId());
                commodityCostAttribute.setCommodityId(commodity.getId());
                BeanUtils.copyProperties(publicParamSet, commodityCostAttribute, EntityUtil.getNullPropertyNames(publicParamSet));
                commodityCostAttributeList.add(commodityCostAttribute);
                // --------------- 设置 商品成本属性 end  ---------------

                // =============== 设置 商品成本 start ===============
                BeanUtils.copyProperties(commodityCostReq, commodityCost, EntityUtil.getNullPropertyNames(commodityCostReq));
                BeanUtils.copyProperties(publicParamSet, commodityCost, EntityUtil.getNullPropertyNames(publicParamSet));
                commodityCost.setCommodityAttributeId(commodityAttribute.getId());
                commodityCost.setCommodityId(commodity.getId());
                commodityCost.setCostAttributeId(commodityCostAttributeId); // 商品成本属性ID
                commodityCostList.add(commodityCost);
                // =============== 设置 商品成本 end ===============
            }
            costAttributeMapper.insertBatchSomeColumn(commodityCostAttributeList);
            costMapper.insertBatchSomeColumn(commodityCostList);
        }
    }

    private void setUpCommodityCost(Commodity commodity, CommodityAttribute commodityAttribute,
                                    CommodityAddReq addReq, PublicParamSet publicParamSet) {
        List<CommodityCostReq> commodityCostReqList = addReq.getCommodityCostReqList();
        if (null != commodityCostReqList && commodityCostReqList.size() > 0) {
            // 注意：单规格，只有一条数据
            CommodityCostReq commodityCostReq = commodityCostReqList.get(0);
            CommodityCost dbCommodityCost = costMapper.selectById(commodityCostReq.getId());
            BeanUtils.copyProperties(commodityCostReq, dbCommodityCost, EntityUtil.getNullPropertyNames(commodityCostReq));
            BeanUtils.copyProperties(publicParamSet, dbCommodityCost, EntityUtil.getNullPropertyNames(publicParamSet));
            dbCommodityCost.setCommodityAttributeId(commodityAttribute.getId());
            dbCommodityCost.setCommodityId(commodity.getId());
            if(dbCommodityCost.getId() != null){
                costMapper.updateById(dbCommodityCost);
            }else{
                costMapper.insert(dbCommodityCost);
            }
        }
    }

    private void setUpCommoditySalesArea(Commodity commodity, CommodityAttribute commodityAttribute, CommodityAddReq addReq,
                                         PublicParamSet publicParamSet) {
        CommoditySalesAreaReq commoditySalesAreaReq = addReq.getCommoditySalesAreaReq();
        List<Integer> areaTypeList = commoditySalesAreaReq.getAreaTypeList();
        if(commoditySalesAreaReq != null && commoditySalesAreaReq.getAreaTypeList() != null){
            boolean flag = false;
            for (Integer integer : areaTypeList) {
                if(integer.equals(1) || integer.equals(2) || integer.equals(3)){
                    flag = true;
                    break;
                }
            }
            if(!flag){
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23016);
            }
        }else{
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23016);
        }
        // 移除后重新添加
        Map<String, Object> map = new HashMap<>();
        map.put("commodity_id", commodity.getId());
        salesAreaMapper.deleteByMap(map);
        for (Integer areaType : areaTypeList) {
            // 重新新增
            CommoditySalesArea dbCommoditySalesArea = new CommoditySalesArea();
            dbCommoditySalesArea.setId(SnowflakeIdWorker.nextId());
            dbCommoditySalesArea.setCommodityId(commodity.getId());
            dbCommoditySalesArea.setAreaType(areaType);
            if(commodityAttribute != null){
                dbCommoditySalesArea.setCommodityAttributeId(commodityAttribute.getId());
            }
            dbCommoditySalesArea.setGmtCreate(LocalDateTime.now());
            dbCommoditySalesArea.setCreateId(commodity.getCreateId());
            dbCommoditySalesArea.setModifiedId(publicParamSet.getModifiedId());
            dbCommoditySalesArea.setIsDeleted(0);
            salesAreaMapper.insert(dbCommoditySalesArea);
        }
    }


    @Override
    public List<CommodityDTO> selectCommodityDTOListByIds(List<Long> ids) {
        List<Commodity> commodities = commodityMapper.selectBatchIds(ids);
        return EntityUtil.copyList(commodities, CommodityDTO.class);
    }

    @Override
    public List<CountVo> findSavenDaysCommodityNumber() {
        return commodityMapper.findSavenDaysCommodityNumber();
    }

    @Override
    public Result<CommoditySeasonDTO> findCommodityPriceById(Long commodityId, LocalDate currentDateTime, Long specificationsAttributeOneId, Long specificationsAttributeTwoId) {
        return commodityMapper.findCommodityPriceById(commodityId, currentDateTime, specificationsAttributeOneId, specificationsAttributeTwoId);
    }

    @Override
    public JSONObject findCommodityAttributesListById(Long id) {
        JSONObject jsonObject = new JSONObject();
        CommodityDTO2 commodityDTO = commodityMapper.findCOmmodityInfoByCommodityId(id);
        if(commodityDTO != null){
            // 产品基本信息
            JSONObject commodityJsonObject = new JSONObject();
            commodityJsonObject.put("id", commodityDTO.getId());
            commodityJsonObject.put("commodityName", commodityDTO.getCommodityName());
            commodityJsonObject.put("commodityNumber", commodityDTO.getCommodityNumber());
            commodityJsonObject.put("commodityIntroduce", commodityDTO.getCommodityIntroduce());
            // 运费模板及配送区域信息
            JSONObject freightTemplateJsonObject = new JSONObject();
            freightTemplateJsonObject.put("freightTemplateId", commodityDTO.getFreightTemplateId());
            freightTemplateJsonObject.put("templateName", commodityDTO.getTemplateName());
            // 配送区域
            if(commodityDTO.getFreightTemplateId() != null){
                List<RegionalFreight> regionalFreightList = regionalFreightMapper.findBatchFreightByTemplateId(commodityDTO.getFreightTemplateId());
                freightTemplateJsonObject.put("regionalFreightList", regionalFreightList!=null?regionalFreightList:new ArrayList<>());
            }
            commodityJsonObject.put("freightTemplateDetail", freightTemplateJsonObject);

            // 产品文件信息
            List<CommodityFile> commodityFiles = fileMapper.findHtmlFiveCommodityFileByCommodityId(commodityDTO.getId());
            if(commodityFiles != null && commodityFiles.size() > 0){
                List<JSONObject> fileObjects = new ArrayList<>();
                commodityFiles.stream().forEach(item -> {
                    JSONObject fileObject = new JSONObject();
                    fileObject.put("id", item.getId());
                    fileObject.put("fileName", item.getFileName());
                    fileObject.put("fileType", item.getFileType());
                    fileObject.put("fileUrl", item.getFileUrl());
                    fileObjects.add(fileObject);
                });
                commodityJsonObject.put("commodityFileList", fileObjects);
            }else{
                commodityJsonObject.put("commodityFileList", new ArrayList<>());
            }

            // 保存属性信息用以后面的查询结果过滤，不然会显示所有的规格属性的
            List<JSONObject> commodityCostAttributeList = new ArrayList<>();

            // 商品规格属性信息
            CommodityAttribute commodityAttribute = attributeMapper.findCommodityAttributeByCommodityId(commodityDTO.getId());
            if(commodityAttribute != null){
                JSONObject commodityAttributeJsonObject = new JSONObject();
                commodityAttributeJsonObject.put("id", commodityAttribute.getId());
                commodityAttributeJsonObject.put("specificationsType", commodityAttribute.getSpecificationsType());
                commodityAttributeJsonObject.put("currencyId", commodityAttribute.getCurrencyId());
                commodityAttributeJsonObject.put("currencyName", commodityAttribute.getCurrencyName());
                jsonObject.put("commodityAttribute", commodityAttributeJsonObject);

                // 查询商品关联的属性列表ID
                List<CommodityCostAttribute> commodityCostAttributes = commodityCostAttributeMapper.selectListByCostIdAndCommodityId(commodityAttribute.getId(), commodityAttribute.getCommodityId());
                if(commodityCostAttributes != null && commodityCostAttributes.size() > 0){
                    for (CommodityCostAttribute commodityCostAttribute : commodityCostAttributes) {
                        if(commodityCostAttribute.getSpecificationsAttributeOneId() != null && commodityCostAttribute.getSpecificationsAttributeOneName() != null){
                            JSONObject oneObject = new JSONObject();
                            oneObject.put("id", commodityCostAttribute.getSpecificationsAttributeOneId());
                            oneObject.put("name", commodityCostAttribute.getSpecificationsAttributeOneName());
                            commodityCostAttributeList.add(oneObject);
                        }
                        if(commodityCostAttribute.getSpecificationsAttributeTwoId() != null && commodityCostAttribute.getSpecificationsAttributeTwoName() != null){
                            JSONObject twoObject = new JSONObject();
                            twoObject.put("id", commodityCostAttribute.getSpecificationsAttributeTwoId());
                            twoObject.put("name", commodityCostAttribute.getSpecificationsAttributeTwoName());
                            commodityCostAttributeList.add(twoObject);
                        }
                    }
                }
            }
            jsonObject.put("commodityDetail", commodityJsonObject);


            if(commodityDTO.getCommoditySpecificationsNameId() != null){
                List<JSONObject> arr1 = new ArrayList<>();
                // 查询规格
                List<CommoditySpecifications> commoditySpecificationsList = commoditySpecificationsMapper.findBatchSpecificationsByNameId(commodityDTO.getCommoditySpecificationsNameId());
                for (CommoditySpecifications commoditySpecifications : commoditySpecificationsList) {
                    String specificationsName = commoditySpecifications.getSpecifications();
                    Long specificationsId = commoditySpecifications.getId();
                    JSONObject jsonObject1 = new JSONObject();
                    jsonObject1.put("id", specificationsId);
                    jsonObject1.put("specificationsName", specificationsName);

                    List<CommoditySpecificationsAttribute> commoditySpecificationsAttributeList = commoditySpecificationsAttributeMapper.findCommoditySpecificationsAttributeListByNameIdAndSId(commodityDTO.getCommoditySpecificationsNameId(), commoditySpecifications.getId());
                    if(commoditySpecificationsAttributeList != null && commoditySpecificationsAttributeList.size() > 0){
                        List<JSONObject> array = new ArrayList<>();
                        commoditySpecificationsAttributeList.stream().forEach(item -> {
                            commodityCostAttributeList.forEach(item2 -> {
                                if (item2.getLong("id").equals(item.getId())){
                                    JSONObject jsonObject2 = new JSONObject();
                                    jsonObject2.put("id", item.getId());
                                    jsonObject2.put("attributeName", item.getAttributeName());
                                    array.add(jsonObject2);
                                }
                            });
                        });
                        jsonObject1.put("speficationsAttributeList", array);
                    }else{
                        jsonObject1.put("speficationsAttributeList", new ArrayList<>());
                    }

                    arr1.add(jsonObject1);
                }
                System.out.println(arr1);
                jsonObject.put("specificationsList", arr1);
            }

            // 规格价格信息
            List<CommodityCost> commodityCostList = costMapper.findCommodityCostListByCommodityId(commodityDTO.getId());
            commodityCostList = commodityCostList == null ? new ArrayList<>() : commodityCostList;
            jsonObject.put("commodityCostList", commodityCostList);
        }
        return jsonObject;
    }

    // 商品编码 PS+員工編號+月日4位+時分4位+4位隨機數字
    public String generateCommodityNumber(TokenUser currentUser){
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        String mMddHHmm = nowLocalDateTime.format(DateTimeFormatter.ofPattern("MMddHHmm"));
        String randomFourNumber = CharUtil.getNumber(0, 4);
        return "PS" + currentUser.getEmployeeNumber() + mMddHHmm + randomFourNumber;
    }
}